﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using Silvermoon.Controls;
using Silvermoon.Images;
using Microsoft.WindowsMobile.PocketOutlook;
using OutlookHub.Styles;
using OutlookHub.Utils;
using Silvermoon.OpenGL;
using Silvermoon.Controls.Buttons;
using OutlookHub.Controls;
using Silvermoon.Windows;
using Silvermoon.Controls.Forms;
using Silvermoon.UI;
using Silvermoon.Shapes;
using Silvermoon.Classes;
using System.Diagnostics;
using OutlookHub.Classes;


namespace OutlookHub.Pages
{
    public class EditTaskDetailsPage : Page
    {
        private Task task;

        private ToolbarButton delBtn;
        private ScrollStackPanel panel1;
        private static Margin itemMargin = new Margin(4, 4, VScrollBar.ScrollbarWidth + 1, 4);
        private TabControl tabs;
        private TextBox subjectTb, categoriesTb;
        private DropDownBox importanceDropDown;
        private DropDownBox statusDropDown;
        private DatePicker startDateTb;
        private DatePicker dueDateTb;
        private Control reminderDateLabel, reminderTimeLabel;
        private ToggleSwitchControl reminderTs;
        private DropDownBox occuranceDropDown;
        private DatePicker reminderDateTb;
        private TimePicker reminderTimeTb;
        private DropDownBox sensitivityDropDown;
        private TextBox details;
        private int startOffset = 0;

        public EditTaskDetailsPage()
            : base()
        {
            InitializePage();
        }

        public Task Task
        {
            get { return task; }
            set
            {
                if (task != value)
                {
                    task = value;
                    OnTaskChanged();
                }
            }
        }

        public bool IsDetailsParent { get; set; }

        public bool IsDeleteEnabled
        {
            get { return delBtn.Enabled; }
            set { delBtn.Enabled = value; }
        }

        private void OnTaskChanged()
        {
            if (task != null)
            {
                subjectTb.Text = task.Subject;
                importanceDropDown.SelectedItemIndex = (int)task.Importance;
                startDateTb.Date = task.StartDate;
                dueDateTb.Date = task.DueDate;
                bool reminder = task.ReminderSet;
                reminderTs.IsChecked = reminder;
                reminderDateTb.Date = task.ReminderTime.Date;
                reminderTimeTb.Time = task.ReminderTime.TimeOfDay;
                reminderDateLabel.Visible = reminder;
                reminderTimeLabel.Visible = reminder;
                reminderDateTb.Visible = reminder;
                reminderTimeTb.Visible = reminder;
                details.Text = task.Body;
                categoriesTb.Text = task.Categories;

                statusDropDown.SelectedItemIndex = task.Complete ? 0 : 1;
                occuranceDropDown.SelectedItemIndex = ToIndex(task.RecurrencePattern.RecurrenceType);
                sensitivityDropDown.SelectedItemIndex = (int)task.Sensitivity;
            }
        }

        private int ToIndex(RecurrenceType recurrenceType)
        {
            switch (recurrenceType)
            {
                case RecurrenceType.NoRecurrence: return 0;
                case RecurrenceType.Daily: return 1;
                case RecurrenceType.Weekly: return 2;
                case RecurrenceType.Monthly: return 3;
                case RecurrenceType.Yearly: return 4;
                default: return 5;
            }
        }

        private void InitializePage()
        {
            SetTransition(350, TransitionMask.RotateLeftIn, TransitionMask.RotateLeftIn);
            Styles = StylePool.TaskDetails;

            Title = "EDIT TASK";
            tabs = new TabControl { Margin = Margin.Zero };
            Controls.Add(tabs);
            ScrollStackPanel panel = new ScrollStackPanel { Margin = Margin.Zero };

            Label l = GetLabel("Subject");
            subjectTb = new TextBox { Margin = new Margin(4, 4, VScrollBar.ScrollbarWidth, null), AutoHeight = true, Padding = new Margin(8, 12, 8, 12), AcceptReturn = true };
            panel.Controls.Add(l, subjectTb);
            panel1 = panel;

            l = GetLabel("Start");
            startDateTb = new DatePicker { Margin = new Margin(4), Height = 64 };
            startDateTb.TextChanged += new EventHandler(startDateTb_TextChanged);
            panel.Controls.Add(l, startDateTb);

            l = GetLabel("Due");
            dueDateTb = new DatePicker { Margin = new Margin(4), Height = 64 };
            dueDateTb.TextChanged += new EventHandler(dueDateTb_TextChanged);
            panel.Controls.Add(l, dueDateTb);

            l = GetLabel("Categories");
            categoriesTb = new TextBox { Margin = new Margin(4), Height = 64, AllowPress = true, ReadOnly = true, AcceptReturn = true, AutoHeight = true, Font = SystemFonts.Normal };
            categoriesTb.Tap += new EventHandler<TapEventArgs>(OnSelectCategories);
            panel.Controls.Add(l, categoriesTb);

            l = GetLabel("Occurance");
            occuranceDropDown = new DropDownBox { Margin = itemMargin, ItemHeight = 64 };
            occuranceDropDown.GetVirtualItem += (s, e) => e.Item = new TextItem(e.Value as string);
            occuranceDropDown.ItemsSource = new string[] { "once", "every week day", "every month", "every year", "custom" };
            panel.Controls.Add(l, occuranceDropDown);


            l = GetLabel("Priority");
            importanceDropDown = new DropDownBox { Margin = itemMargin, ItemHeight = 64 };
            importanceDropDown.GetVirtualItem += (s, e) => e.Item = new TextItem(e.Value as string);
            importanceDropDown.ItemsSource = new string[] { "low", "normal", "high" };
            panel.Controls.Add(l, importanceDropDown);

            l = GetLabel("Sensitivity");
            sensitivityDropDown = new DropDownBox { Margin = itemMargin, ItemHeight = 64 };
            sensitivityDropDown.GetVirtualItem += (s, e) => e.Item = new TextItem(e.Value as string);
            sensitivityDropDown.ItemsSource = new string[] { "normal", "personal", "private", "confidental" };
            panel.Controls.Add(l, sensitivityDropDown);

            l = GetLabel("Status");
            statusDropDown = new DropDownBox { Margin = itemMargin, ItemHeight = 64 };
            statusDropDown.GetVirtualItem += (s, e) => e.Item = new TextItem(e.Value as string);
            statusDropDown.ItemsSource = new string[] { "completed", "incomplete" };
            panel.Controls.Add(l, statusDropDown);

            tabs.Pages.Add(new TabPage("details", panel));
            panel = new ScrollStackPanel { Margin = Margin.Zero };

            l = GetLabel("Reminder");
            reminderTs = new ToggleSwitchControl { Margin = new Margin(4, 0, VScrollBar.ScrollbarWidth, 4), Height = 64 };
            reminderTs.CheckedChanged += (s, e) => { task.ReminderSet = reminderTs.IsChecked; OnTaskChanged(); };
            panel.Controls.Add(l, reminderTs);
            l = GetLabel("Date");
            reminderDateLabel = l;
            reminderDateTb = new DatePicker { Margin = new Margin(4), Height = 64 };
            panel.Controls.Add(l, reminderDateTb);

            l = GetLabel("Time");
            reminderTimeLabel = l;
            reminderTimeTb = new TimePicker { Margin = new Margin(4), Height = 64 };
            panel.Controls.Add(l, reminderTimeTb);
            tabs.Pages.Add(new TabPage("reminder", panel));

            panel = new ScrollStackPanel { Margin = Margin.Zero };
            details = new TextBox { AutoHeight = true, Margin = new Margin(4, 4, VScrollBar.ScrollbarWidth, 4), AcceptReturn = true, Font = SystemFonts.Medium };
            panel.Controls.Add(details);
            tabs.Pages.Add(new TabPage("notes", panel));


            Toolbar tb = new Toolbar();
            tb.AddButton(SysImages.Ok).Tap += new EventHandler<TapEventArgs>(OnOK);
            delBtn = tb.AddButton(SysImages.RecycleBin);
            delBtn.Tap += new EventHandler<TapEventArgs>(OnDeleteTask);
            tb.AddButton(SysImages.Cancel, Page.BackCommand);
            Toolbar = tb;
        }

        void dueDateTb_TextChanged(object sender, EventArgs e)
        {
            DateTime startDate = startDateTb.Date;
            DateTime dueDate = dueDateTb.Date;
            if (DueDateIsLowerThanStartDate(startDate, dueDate))
            {
                startDateTb.Date = dueDate;
            }
        }

        void startDateTb_TextChanged(object sender, EventArgs e)
        {
            DateTime startDate = startDateTb.Date;
            DateTime dueDate = dueDateTb.Date;
            if (DueDateIsLowerThanStartDate(startDate, dueDate))
            {
                dueDateTb.Date = startDate;
            }

        }

        void OnSelectCategories(object sender, TapEventArgs e)
        {
            CategoriesPage page = new CategoriesPage();
            page.Selected += (s, ee) =>
                {
                    task.Categories = page.SelectedCategories.AsCommaDelimitedString();
                };
            page.SelectedCategories = task.Categories.SplitByComma();
            SaveChanges();
            this.NavigateTo(page);
        }


        void OnDeleteTask(object sender, TapEventArgs e)
        {
            if (task == null) throw new ArgumentNullException("task");
            MessageDialog.Show("DELETE TASK", "Delete task " + task.Subject + "?", "Delete", "Cancel", DeleteTask, null);
        }

        private void DeleteTask()
        {
            if (task == null) throw new ArgumentNullException("task");
            task.Delete();
            GoBack();
        }


        void OnOK(object sender, TapEventArgs e)
        {
            SaveChanges();
            OnAccept();
            GoBack();
        }

        private void OnAccept()
        {
            if (Accept != null) Accept(this, new TaskEventArgs(task));
        }

        private void SaveChanges()
        {
            try
            {
                if (task != null)
                {
                    task.Subject = subjectTb.Text;
                    task.Body = details.Text;
                    task.StartDate = startDateTb.Date;
                    task.DueDate = dueDateTb.Date;
                    if (DueDateIsLowerThanStartDate(task.StartDate, task.DueDate)) task.DueDate = task.StartDate;
                    task.ReminderSet = reminderTs.IsChecked;
                    task.ReminderTime = GetReminderTime();
                    task.Sensitivity = (Sensitivity)sensitivityDropDown.SelectedItemIndex;
                    task.Complete = statusDropDown.SelectedItemIndex == 0;
                    task.Importance = (Importance)importanceDropDown.SelectedItemIndex;
                }
            }
            catch (Exception ex)
            {
                MessageDialog.Show("ERROR", ex.Message);
                if (Debugger.IsAttached) Trace.WriteLine(ex.StackTrace);
            }
        }

        private bool DueDateIsLowerThanStartDate(DateTime startDate, DateTime dueDate)
        {
            if (startDate.IsEmpty()) return false;
            if (dueDate.IsEmpty()) return true;
            return dueDate < startDate;
        }

        private DateTime GetReminderTime()
        {
            DateTime time = reminderDateTb.Date.Date;
            return time.Add(reminderTimeTb.Time);
        }

        private Label GetLabel(string text)
        {
            return new Label { Text = text, AutoSize = true, Margin = new Margin(0, 24, 0, 4), TextColor = PhoneColors.Accent };
        }

        private class Bag
        {
            public event EventHandler<TaskEventArgs> Accept;
            public bool IsDetailsParent;
            public Task Task;
            public int Offset;

            public void SetPage(EditTaskDetailsPage page)
            {
                page.Accept += this.Accept;
            }
        }

        public override object OnSaveViewState()
        {
            Bag bag = new Bag { Task = this.Task, Offset = panel1.YOffset, IsDetailsParent = this.IsDetailsParent };
            bag.Accept += this.Accept;
            return bag;
        }

        public override void OnLoadViewState(object viewState)
        {
            Bag bag = viewState as Bag;
            if (bag != null)
            {
                bag.SetPage(this);
                IsDetailsParent = bag.IsDetailsParent;
                Task = bag.Task;
                PreLoad();

                startOffset = bag.Offset;
                panel1.YOffset = startOffset;
            }
        }


        protected override void OnBack(HandledEventArgs e)
        {
            if (!IsDetailsParent) NavigateBack(2); else base.OnBack(e);
        }


        public event EventHandler<TaskEventArgs> Accept;
    }
}
